package service

import (
	"errors"
	"fmt"
	"go.uber.org/zap"
	"iot-base/common/cache"
	"iot-base/common/ctrltype"
	"iot-base/common/logger"
	"iot-base/devc/common/loader"
)

type handler func(id string, thing *cache.ThingInfo, v interface{}, round int64) (interface{}, error)
type svHandler func(pCmd *ctrltype.CtrlCmd, tingInfo *cache.ThingInfo) (map[string]interface{}, error)

var handlerMap map[string]handler
var svHandlerMap map[string]svHandler

func init() {
	handlerMap = map[string]handler{
		"m_pm10": NewPMLogic().PM,
		"m_pm25": NewPMLogic().PM,
		"m_co":   NewCoLogic().Co,
		"m_nox":  NewNoxLogic().Nox,
		"m_so2":  NewSo2Logic().So2,
		"m_o3":   NewO3Logic().O3,
	}
	svHandlerMap = map[string]svHandler{
		"m_co":   NewCoLogic().CoSv,
		"m_nox":  NewNoxLogic().NoxSv,
		"m_so2":  NewSo2Logic().So2Sv,
		"m_o3":   NewO3Logic().O3Sv,
		"m_calo": NewCaloLogic().CaloSv,
		"m_pm10": NewPMLogic().PMSv,
		"m_pm25": NewPMLogic().PMSv,
	}
}

func StartService(id string, thing *cache.ThingInfo, v interface{}, round int64) (interface{}, error) {
	logger.Log.Info("service id and thing", zap.Any("id", id), zap.Any("thing", thing))
	modelId := thing.Thing.ModelID
	fmt.Println("model_id", modelId)
	if f, ok := handlerMap[modelId]; ok {
		return f(id, thing, v, round)
	}
	return nil, errors.New("no this modelId imp")
}

func Sv() {
	loader.SubCtrlHandler(func(pCmd *ctrltype.CtrlCmd) (map[string]interface{}, error) {
		tingInfo, err := cache.GetThing(pCmd.ThingID)
		if err != nil {
			logger.Log.Error("get thing msg err", zap.Error(err))
			return nil, errors.New("get thing msg err:" + err.Error())
		}
		if f, ok := svHandlerMap[tingInfo.Thing.ModelID]; ok {
			fmt.Println("pCmd id:", pCmd.ID)
			fmt.Println("tingInfo.Thing.ModelID:", tingInfo.Thing.ModelID)
			return f(pCmd, tingInfo)
		} else {
			logger.Log.Error("no this func:")
			return nil, errors.New("no this function")
		}
	})
}
